﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using PresentacionWindows.Base;
using Negocio.Generico;
using Negocio.View;
using Integra.Comun;
using System.IO;
using PresentacionWindows.Reports;
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.Shared;
//using CrystalDecisions.CrystalReports.Engine;
//using CrystalDecisions.Shared;

namespace PresentacionWindows
{
    public partial class frmMain : FormBase
    {
        #region propiedades

        private List<AsignaturaDTO> listaAsig = new List<AsignaturaDTO>();

        private List<DateTime> listaFechas = new List<DateTime>();
        private List<String> listaEventos = new List<string>();
        private List<RenglonDTO> listaRenglones = new List<RenglonDTO>();


        #endregion

        #region Constructor, Incializadores

        public frmMain(PersonaDTO tokenUsuario)
        {
            this.TokenUsuario = tokenUsuario;
            InitializeComponent();

            IniciarFormulario();
        }

        /// <summary>
        /// Incializa el formulario
        /// </summary>
        public void IniciarFormulario()
        {
            try
            {
                if (TokenUsuario.EsAdministrador == (int)OpcionSiNo.No)
                {
                    grpInformacionPers.Visible = true;
                    grpCalendario.Visible = true;
                    grpEventosProximos.Visible = true;
                    grpAsignaturas.Visible = true;
                    pnlAdministrador.Visible = false;

                    CargaInformacionPersonal();
                    CargaAsignaturas();
                    CargaEventosProximos();
                    this.Text = "Portal de gestión de contenidos";
                }
                else
                {
                    //Eventos del administrador
                    foreach (Control crt in this.Controls)
                    {
                        crt.Visible = false;
                    }
                    pnlAdministrador.Visible = true;
                    archivoToolStripMenuItem.Visible = true;
                    this.grdProfesores.SelectionChanged -= new System.EventHandler(this.grdProfesores_SelectionChanged);
                    RecargaGrid();
                   
                    CargaDatosProfesorSeleccionado();
                    this.grdProfesores.SelectionChanged += new System.EventHandler(this.grdProfesores_SelectionChanged);

                    this.Text = "Portal de administración de profesores";

                }

            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
        }


        #endregion

        #region Funciones propias

        /// <summary>
        /// Metodo que carga la informacion persona de usuario
        /// </summary>
        private void CargaInformacionPersonal()
        {
            try
            {
                //Cargamos el listado de asignaturas del profesor
                AsignaturaView vista = AsignaturaView.GetInstance();
                AsignaturaDTO filtro = new AsignaturaDTO();
                filtro.CoProfesor = TokenUsuario.CoProfesor;

                DataTable dt = vista.GetAsignaturasViewByAsignatura(filtro).Table;
                int i = 0;
                foreach (DataRow dr in dt.Rows)
                {
                    AsignaturaDTO objeto = new AsignaturaDTO();
                    objeto.CoAsignatura = Int32.Parse(dr["CODIGOASIGNATURA"].ToString());
                    objeto.CoProfesor = Int32.Parse(dr["CODIGOPROFESOR"].ToString());
                    objeto.CoTitulacion = Int32.Parse(dr["CODIGOTITULACION"].ToString());
                    objeto.CreditosAsig = Int32.Parse(dr["CREDITOSASIG"].ToString());
                    objeto.Nombre = dr["NOMBRE"].ToString();
                    listaAsig.Add(objeto);

                    Label etiqueta = new Label();
                    etiqueta.Text = objeto.Nombre;
                    etiqueta.Location = new System.Drawing.Point(6, (i + 1) * 20);
                    etiqueta.Size = new System.Drawing.Size(121, 18);
                    grpAsignaturas.Controls.Add(etiqueta);
                    i++;
                }

                //Cargamos los datos del profesor dentro del apartado de informacion personal
                //TODO: Implementar cuando se haya completado el login
                if (TokenUsuario.Imagen == null)
                {
                    MemoryStream ms = new MemoryStream(TokenUsuario.Imagen);
                    Image img = Image.FromStream(ms);
                    pbImagenPersonal.Image = img;
                }
                else
                {
                    pbImagenPersonal.Image = Image.FromFile(@"C:\Users\Cr\Desktop\jhon.jpeg");
                }
                lblContenidoApellidos.Text = "";
                lblContenidoEmail.Text = "";
                lblContenidoNombre.Text = "";

                lblContenidoApellidos.Text = TokenUsuario.Apellido1 + " " + TokenUsuario.Apellido2;
                lblContenidoEmail.Text = TokenUsuario.Email;
                lblContenidoNombre.Text = TokenUsuario.Nombre;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// Carga los listados de las asignaturas
        /// </summary>
        private void CargaAsignaturas()
        {
            try
            {
                //AsignaturaDTO bean = new AsignaturaDTO();
                //bean.CoProfesor = this.TokenUsuario.CoProfesor;
                //AsignaturaView vista = AsignaturaView.GetInstance();
                //DataTable dt = vista.GetAsignaturasViewByAsignatura(bean).Table;
                //foreach (DataRow dr in dt.Rows)
                //{
                //    Label lbl = new Label();
                //    lbl.Text = dr["NOMBRE"].ToString();
                //    grpAsignaturas.Controls.Add(lbl);
                //}
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// Cargo los eventos del mes
        /// </summary>
        private void CargaEventosProximos()
        {
            try
            {

                foreach (AsignaturaDTO obj in listaAsig)
                {
                    //Obtenemos para cada una de ellas renglones y sus fechas de requerimiento
                    RenglonView vista = RenglonView.GetInstance();
                    RenglonDTO filtro = new RenglonDTO();
                    filtro.CoAsignatura = obj.CoAsignatura;
                    DataTable dt = vista.GetViewRenglon(filtro).Table;

                    if (dt.Rows.Count > 0)
                    {
                        foreach (DataRow dr in dt.Rows)
                        {
                            if (dr["CODIGOTIPORENGLON"].ToString() != "")
                            {
                                switch (Int32.Parse(dr["CODIGOTIPORENGLON"].ToString()))
                                {
                                    case (int)TipoRenglon.Practicas:
                                        listaFechas.Add(DateTime.Parse(dr["FECHAREQUERIMIENTO"].ToString()));
                                        listaEventos.Add(DateTime.Parse(dr["FECHAREQUERIMIENTO"].ToString()).ToShortDateString() + " - Practicas: " + dr["NOMBRE"].ToString());
                                        RenglonDTO renglon = new RenglonDTO();
                                        renglon = rellenaRenglon(dr, TipoRenglon.Practicas);
                                        listaRenglones.Add(renglon);
                                        break;
                                    case (int)TipoRenglon.Examen:
                                        listaFechas.Add(DateTime.Parse(dr["FECHAREQUERIMIENTO"].ToString()));
                                        listaEventos.Add(DateTime.Parse(dr["FECHAREQUERIMIENTO"].ToString()) + " - Examen: " + dr["NOMBRE"].ToString());
                                        RenglonDTO renglonExamen = new RenglonDTO();
                                        renglonExamen = rellenaRenglon(dr, TipoRenglon.Examen);

                                        listaRenglones.Add(renglonExamen);
                                        break;
                                }

                            }
                        }
                    }
                }

                //Cargamos las fechas dentro del calendario
                listaFechas.Sort();
                calendario.BoldedDates = listaFechas.ToArray();
                int i = 0;
                //Cargamos los eventos en el groupbox de los eventos
                foreach (string s in listaEventos)
                {
                    Label etiqueta = new Label();
                    etiqueta.Text = s.ToString();
                    etiqueta.Location = new System.Drawing.Point(6, (i + 1) * 20);
                    etiqueta.Size = new System.Drawing.Size(226, 16);
                    grpEventosProximos.Controls.Add(etiqueta);
                    i++;
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private RenglonDTO rellenaRenglon(DataRow dr, TipoRenglon tipo)
        {
            try
            {
                RenglonDTO renglon = new RenglonDTO();
                renglon.CoRenglon = Int32.Parse(dr["CODIGORENGLON"].ToString());
                renglon.CoTipoRenglon = (int)tipo;
                renglon.FchRequerimiento = DateTime.Parse(dr["FECHAREQUERIMIENTO"].ToString());
                renglon.Nombre = dr["NOMBRE"].ToString();
                renglon.FchCreacion = DateTime.Parse(dr["FECHACREACION"].ToString());
                renglon.Descripcion = dr["DESCRIPCION"].ToString();
                if (!dr.IsNull("PUBLICO"))
                {
                    if (Boolean.Parse(dr["PUBLICO"].ToString()))
                    {
                        renglon.Publico = true;
                    }
                    else
                    {
                        renglon.Publico = false;
                    }
                }
                renglon.CoAsignatura = Int32.Parse(dr["CODIGOASIGNATURA"].ToString());

                return renglon;

            }
            catch (Exception ex)
            {
                this.MostrarExcepcion(ex);
            }
            return null;
        }

        #endregion

        #region Eventos
        private void ponerNotasToolStripMenuItem_Click(object sender, EventArgs e)
        {
            uscAsignaturas usc = new uscAsignaturas(this.TokenUsuario);
            this.Contenedor.Controls.Add(usc);
        }


        private void tsbArchivo_Click(object sender, EventArgs e)
        {

        }

        private void tsbAsignaturas_Click(object sender, EventArgs e)
        {
            Contenedor.Controls.Clear();
            uscAsignaturas controlAsignaturas = new uscAsignaturas(this.TokenUsuario);
            Contenedor.Controls.Add(controlAsignaturas);
        }

        private void tsbNotificaciones_Click(object sender, EventArgs e)
        {

            Contenedor.Controls.Clear();
            uscRenglones usc = new uscRenglones(this.TokenUsuario);
            Contenedor.Controls.Add(usc);
        }

        private void tsbClase_Click(object sender, EventArgs e)
        {
            try
            {
                this.Contenedor.Controls.Clear();
                uscClase usc = new uscClase(this.TokenUsuario);
                this.Contenedor.Controls.Add(usc);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error en la carga de los datos de clase. Error:" + ex.Message);
            }
        }

        private void tsbAcerca_Click(object sender, EventArgs e)
        {
            uscAcercaDe usr = new uscAcercaDe();
            Contenedor.Controls.Clear();
            Contenedor.Controls.Add(usr);
        }

        private void iniciarSesionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            
            frmLogin frm = new frmLogin();
            frm.ShowDialog();
            this.Close();
          
            Contenedor.Controls.Clear();
            //Contenedor.Controls.Add(uscLog);
        }

        private void renglonesToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }


        private void salirDeLaAplicaciónToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void tsbRenglon_Click(object sender, EventArgs e)
        {

            try
            {
                this.Contenedor.Controls.Clear();
                uscNotas usc = new uscNotas(this.TokenUsuario);
                usc.formulario = this;
                this.Contenedor.Controls.Add(usc);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error en la carga de las notas. Error:" + ex.Message);
            }
        }

        private void calendario_DateSelected(object sender, DateRangeEventArgs e)
        {
            try
            {
                //calendario.Se
            }
            catch (Exception ex)
            {
                this.MostrarExcepcion(ex);
            }
        }
        #endregion

        private void calendario_DateChanged(object sender, DateRangeEventArgs e)
        {
            foreach (RenglonDTO renglon in listaRenglones)
            {
                if (DateTime.Parse(renglon.FchRequerimiento.ToString()).ToShortDateString() == calendario.SelectionStart.ToShortDateString())
                {
                    frmRenglon frm = new frmRenglon(renglon, true);
                    frm.ShowDialog();
                }

            }
        }

        #region Eventos y funciones del administrador

        private bool bEditando = false;

        private void BorrarControles() 
        {
            this.txtApellido1.Text = "";
            this.txtApellido2.Text = "";
            this.txtNombre.Text = "";
            this.txtrutaDocumento.Text = "";
            this.txtDNI.Text = "";
            this.txtNick.Text = "";
        }


        private void btnBorrar_Click(object sender, EventArgs e)
        {
            this.txtNombreBusqueda.Text = "";
            this.txtApellido1Busqueda.Text = "";
            this.txtApellido2Busqeuda.Text = "";
            this.txtDNIBusqueda.Text = "";
        }

        private void btnBuscar_Click(object sender, EventArgs e)
        {
            ProfesorDTO filtro = new ProfesorDTO();
            filtro.Nombre = this.txtNombreBusqueda.Text;
            filtro.Apellido1 = this.txtApellido1Busqueda.Text;
            filtro.Apellido2 = this.txtApellido2Busqeuda.Text;
            filtro.Dni = this.txtDNIBusqueda.Text;
            //filtro.Userhash = this.txtPass.Text;
            this.RecargaGrid(filtro);
        }

        private void btnAñadirProfesor_Click(object sender, EventArgs e)
        {
            BloquearControles(true);
        }

        private void btnModificarProfesor_Click(object sender, EventArgs e)
        {
            bEditando = true;
            BloquearControles(true);
        }

        private void btnGuardarProfesor_Click(object sender, EventArgs e)
        {
            try
            {
                GenericaView obj = GenericaView.GetInstance();
                ProfesorDTO bean = null;
                if (!bEditando)
                {
                    bean = new ProfesorDTO();
                    bean.Nombre = txtNombre.Text;
                    bean.Apellido1 = this.txtApellido1.Text;
                    bean.Apellido2 = this.txtApellido2.Text;
                    bean.Dni = this.txtDNI.Text;
                    bean.Email = this.txtEmail.Text;
                    bean.NivelEstudios = "Ingeniero Superior";

                    FileStream FilStr = new FileStream(txtrutaDocumento.Text, FileMode.OpenOrCreate);
                    BinaryReader BinRed = new BinaryReader(FilStr);
                    bean.Imagen = BinRed.ReadBytes((int)BinRed.BaseStream.Length);
                    string passGenerada = GeneradorPassword.GetPassword();
                    bean.Userhash = md5(passGenerada);

                    //Generamos el report con la contraseña
                    PWDGenerado impreso = new PWDGenerado();
                    //impreso.SetDataSource(bean);


                    ParameterFieldDefinition parameter;
                    ParameterValues paramValues;
                    ParameterDiscreteValue paramValue; try
                    {
                        parameter = impreso.DataDefinition.ParameterFields["Contrasenia"];
                        if (parameter != null)
                        {
                            paramValues = parameter.CurrentValues;
                            paramValue = new ParameterDiscreteValue();
                            paramValue.Value = passGenerada;
                            paramValues.Add(paramValue);
                            parameter.ApplyCurrentValues(paramValues);
                        }
                    }
                    catch { }
                    ControlReports.VistaPrevia(impreso, this);

                    if (obj.Inserta(bean))
                    {
                        MessageBox.Show("Se ha insertado correctamente el profesor");
                    }
                }
                else
                {
                    ProfesorView objLista = ProfesorView.GetInstance();
                    ProfesorDTO condiciones = new ProfesorDTO();
                    condiciones.CoProfesor = this.grdProfesores.SelectedRows[0].Cells["COPROFESOR"].Value != null ? Int32.Parse(this.grdProfesores.SelectedRows[0].Cells["COPROFESOR"].Value.ToString()) : Int32.MinValue;

                    ProfesorDTO[] listaBean = (ProfesorDTO[])obj.GetSimple(condiciones);

                    bean = listaBean[0];

                    bean.Nombre = txtNombre.Text;
                    bean.Apellido1 = this.txtApellido1.Text;
                    bean.Apellido2 = this.txtApellido2.Text;
                    bean.Dni = this.txtDNI.Text;
                    bean.Email = this.txtEmail.Text;
                    bean.NivelEstudios = "Ingeniero Superior";

                    if (txtrutaDocumento.Text != "")
                    {
                        FileStream FilStr = new FileStream(txtrutaDocumento.Text, FileMode.OpenOrCreate);
                        BinaryReader BinRed = new BinaryReader(FilStr);
                        bean.Imagen = BinRed.ReadBytes((int)BinRed.BaseStream.Length);
                    }
                    if (obj.Actualiza(bean))
                    {
                        MessageBox.Show("Se ha actualizado correctamente el profesor");
                    }
                }
                RecargaGrid();
                BloquearControles(false);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
        }

        private void btnEliminarProfesor_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.grdProfesores.Rows.Count > 0)
                {
                    ProfesorDTO filtro = null;
                    GenericaView vista = GenericaView.GetInstance();
                    foreach (DataGridViewRow dr in grdProfesores.SelectedRows)
                    {
                        filtro = null;
                        filtro = new ProfesorDTO();
                        filtro.CoProfesor = Int32.Parse(dr.Cells["COPROFESOR"].Value.ToString());
                        if (vista.Elimina(filtro))
                        { MessageBox.Show("Se ha eliminado correctamente el profesor"); }
                    }
                    RecargaGrid();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("No se puede eliminar el profesor ya que tiene datos dependientes. Excepcion: " + ex.Message);
            }
        }

        /// <summary>
        /// Funcion que bloquea todos los controles de la aplicacion
        /// </summary>
        /// <param name="bloquear">valor booleano que bloquea los controles en cuestion</param>
        private void BloquearControles(bool bloquear)
        {
       

            if (!bEditando)
            {
                this.txtApellido1.Text = "";
                this.txtApellido2.Text = "";
                this.txtNombre.Text = "";
                this.txtrutaDocumento.Text = "";
                this.txtDNI.Text = "";
                this.txtNick.Text = "";
                txtEmail.Text = "";
            }

            txtNombre.Enabled = bloquear;
            txtApellido1.Enabled = bloquear;
            txtApellido2.Enabled = bloquear;
            txtDNI.Enabled = bloquear;
            txtNick.Enabled = bloquear;
            txtEmail.Enabled = bloquear;


            btnAñadirProfesor.Enabled = !bloquear;
            btnModificarProfesor.Enabled = !bloquear;
            btnEliminarProfesor.Enabled = !bloquear;
            btnGuardarProfesor.Enabled = bloquear;

        }

        private void CargaDatosProfesorSeleccionado()
        {
            try
            {
                if (grdProfesores.SelectedRows.Count == 1)
                {
                    ProfesorDTO objeto = RellenaBean();
                    this.txtNombre.Text = objeto.Nombre;
                    this.txtApellido1.Text = objeto.Apellido1;
                    this.txtApellido2.Text = objeto.Apellido2;
                    this.txtDNI.Text = objeto.Dni;
                    this.txtEmail.Text = objeto.Email;
                    this.txtNick.Text = objeto.Nick;
                    //this.txtPass.Text = objeto.Userhash;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Ha sido imposible carga el profesor");
            }
        }


        /// <summary>
        /// Función que rellena un bean segun una row seleccionada de un grid
        /// </summary>
        /// <returns>Funcion que devuelve un objeto de transporte de asignatura</returns>
        private ProfesorDTO RellenaBean()
        {
            ProfesorDTO objetoEdicion = null;
            try
            {
                DataGridViewRow dr= grdProfesores.SelectedRows[0];
      
                objetoEdicion = new ProfesorDTO();

                objetoEdicion.CoPersona =dr.Cells["COPERSONA"].Value != null ? Int32.Parse(dr.Cells["COPERSONA"].Value.ToString()):Int32.MinValue;

                objetoEdicion.CoProfesor = dr.Cells["COPROFESOR"].Value != null ? Int32.Parse(dr.Cells["COPROFESOR"].Value.ToString()) : Int32.MinValue;
                objetoEdicion.Nombre = dr.Cells["NOMBRE"].Value != null ? (dr.Cells["NOMBRE"].Value.ToString()) : null;
                objetoEdicion.Apellido1 = dr.Cells["APELLIDO1"].Value != null ? (dr.Cells["APELLIDO1"].Value.ToString()) : null;
                objetoEdicion.Apellido2 = dr.Cells["APELLIDO2"].Value != null ? (dr.Cells["APELLIDO2"].Value.ToString()) : null;
                objetoEdicion.Dni = dr.Cells["DNI"].Value != null ? (dr.Cells["DNI"].Value.ToString()) : null;
                objetoEdicion.Email = dr.Cells["EMAIL"].Value != null ? (dr.Cells["EMAIL"].Value.ToString()) : null;
                objetoEdicion.Imagen = dr.Cells["IMAGEN"].Value != null ? String2Image(dr.Cells["IMAGEN"].Value.ToString()) : null;
                objetoEdicion.Nick = dr.Cells["NICK"].Value != null ? dr.Cells["NICK"].Value.ToString() : null;
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.Message);
            }
            return objetoEdicion;
        }


        /// <summary>
        /// Funcion que apartir de una cadena obtiene una Imagen compatible con el formato de la BD
        /// </summary>
        /// <param name="cadena">Contenedor de los parametros del WCF</param>
        /// <returns>Imagen para la BD</returns>
        protected byte[] String2Image(String cadena)
        {
            System.Text.ASCIIEncoding codificador = new System.Text.ASCIIEncoding();
            byte[] bytes = codificador.GetBytes(cadena);

  
            return bytes;
        }


        private void RecargaGrid()
        {
            RecargaGrid(new ProfesorDTO());
        }

        /// <summary>
        /// Método que recarga el grid por completo 
        /// </summary>
        private void RecargaGrid(ProfesorDTO filtro)
        {
            try
            {
                ProfesorView vista = ProfesorView.GetInstance();
                ProfesorDTO dto;
                if (filtro == null)
                {
                    dto = new ProfesorDTO();
                }
                else
                {
                    dto = filtro;
                }
                this.grdProfesores.DataSource = null;
                DataView dw = vista.GetProfesoresView(dto);
                DataTable dt = dw.Table;
                this.grdProfesores.DataSource = dt;
                this.grdProfesores.Refresh();
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
        }


        private void btnOpenDialog_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.ofdDocumento.ShowDialog() == DialogResult.OK)
                {
                    this.txtrutaDocumento.Text = this.ofdDocumento.FileName;
                }
            }
            catch (Exception ex)
            {
                this.MostrarExcepcion(ex);
            }
        }


        public static string md5(string Value)
        {
            System.Security.Cryptography.MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider();
            byte[] data = System.Text.Encoding.ASCII.GetBytes(Value);
            data = x.ComputeHash(data);
            string ret = "";
            for (int i = 0; i < data.Length; i++)
                ret += data[i].ToString("x2").ToLower();
            return ret;
        }


        private void grdProfesores_SelectionChanged(object sender, EventArgs e)
        {
            CargaDatosProfesorSeleccionado();
        }

        private void miPerfilToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Contenedor.Controls.Clear();
            uscMiperfil usc = new uscMiperfil(this.TokenUsuario);
            Contenedor.Controls.Add(usc);
        }

        private void pbImagenPersonal_DoubleClick(object sender, EventArgs e)
        {
            miPerfilToolStripMenuItem_Click(sender, e);
        }

        #endregion
    }
}
